#!/bin/sh
#
# shell/cmd.sh: sending and executing commands/scripts.
#
# $Id: cmd.sh.in 815 2008-12-05 22:23:24Z enki $
# ----------------------------------------------------------------------------
test $lib_script_cmd_sh || {

# ----------------------------------------------------------------------------
: ${prefix:="@prefix@"}
: ${libdir:="${exec_prefix}/lib"}
: ${shlibdir:="${libdir}/sh"}

# ----------------------------------------------------------------------------
. $shlibdir/util.sh
. $shlibdir/std/escape.sh

# cmd_exec <command> [host]
#
# Execute a command on the local or a remote host.
# ---------------------------------------------------------------------------
cmd_exec()
{
 (# Is it a remote file?
  if test -n "$2"; then
    exec="ssh_session '$2' '"`escape_squote "$1"`"'"
  else
    exec="($1)"
  fi

  verbose "Executing command${2:+ on $2}: $1"

# debug "

  eval "$exec")
}

# cmd_script <script> [host]
#
# Execute a script on the local or a remote host.
# ---------------------------------------------------------------------------
cmd_script()
{
  local cmd

  cmd="script=\"`escape_dquote "$1"`\" && (
    exec -a cmd_script bash -c \"\$script\" ||
    exec -a cmd_script sh -c \"\$script\"
  )"

  cmd_exec "$cmd" ${2+"$2"}
}

# cmd_for_each <command> [list...]
#
# Executes a command for each item in the list.
# The special parameter "$^" may be used as a placeholder for the item.
# ---------------------------------------------------------------------------
cmd_for_each()
{
  local cmd=$1 item
  shift
  for item; do
    eval "${cmd//'$^'/$item}"
  done
}

# cmd_some <command> [list...]
# 
# Executes a command for some items in the list. 
# It aborts as soon as a command succeeds and tries on when a command fails.
# ---------------------------------------------------------------------------
cmd_some()
{
  local cmd=$1 item
  shift
  for item; do
    eval "${cmd//'$^'/$item}" && return 0
  done
}

# cmd_every <command> [list...]
# 
# Executes a command for every item in the list. 
# It aborts as soon as a command fails and goes on when a command succeeds.
# ---------------------------------------------------------------------------
cmd_every()
{
  local cmd=$1 item
  shift
  for item; do
    eval "${cmd//'$^'/$item}" || return $?
  done
}

# cmd_filter <command> [list...]
# 
# Filters a list according to a command.
#
# For each list item the command is called. If it returns false, the item is
# omitted from the output. The special parameter "$^" may be used as a 
# placeholder for the item.
# ---------------------------------------------------------------------------
cmd_filter()
{
  local cmd=$1 out= item
  shift
  for item; do
    eval "${cmd//'$^'/$item}" && pushv out "$item"
  done
  test -n "$out" && echo "$out"
}

# cmd_map <command> [list...]
#
# Transforms a list according to a command.
# 
# Behaviour is similar to cmd_filter(), but when the command succeeds, the
# output of the command is taken as item for the resulting list.
# ---------------------------------------------------------------------------
cmd_map()
{
  local cmd=$1 out= item
  shift
  for item; do
    item=`eval "${cmd//'$^'/$item}"` && pushv out "$item"
  done
  test -n "$out" && echo "$out"
}

#--- eof ---------------------------------------------------------------------
lib_script_cmd_sh=:;}
